package dongchel.vrp.clonalselection1;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import dongchel.vrp.entity.Solution;
import dongchel.vrp.general.SimpleComparator;
import dongchel.vrp.general.SimpleCompareObject;

public class Fitness {
	/**
	 * population
	 */
	private List<Solution> population;
	
	/**
	 * weights for objective, penalty, speed and distance to relaxed solution
	 */
	private double objectiveWeight = 1;
	private double penaltyWeight = 1;
	private double speedWeight = 0;
	private double distanceWeight = 1 ;
	
	private double[] objectiveWeights;
	private double[] penaltyWeights;
	
	private List<SimpleCompareObject> compareList;;
	
	public Fitness(){
		
	}
	
	public Fitness(List<Solution> population){
		this.population = population;
	}
	
	public void calculateFitnessForPopulation(){
		List<SimpleCompareObject> compareList = new ArrayList<SimpleCompareObject>();
		for(int i=0;i<population.size();i++){
			SimpleCompareObject sco = new SimpleCompareObject();
			sco.setPosition(i);
			sco.setValue(calculateFitnessForSolution(population.get(i)));
			compareList.add(sco);
		}
		Collections.sort(compareList, new FitnessComparator());
		
		this.compareList = compareList;
	}
	
	/**
	 * calculate fitness value for a solution
	 * @param solution
	 * @return
	 */
	public double calculateFitnessForSolution(Solution solution){
		double f = 0;
		
		f = objectiveWeight*(solution.getObjectiveValue().getRandomSummation(objectiveWeights))
		+ penaltyWeight*solution.getPenaltyValue().getRandomSummation(penaltyWeights)
		+ speedWeight*(solution.getObjectiveSpeed(objectiveWeights)+solution.getPenaltySpeed(penaltyWeights));
		
		return f;
	}

	public List<Solution> getPopulation() {
		return population;
	}

	public void setPopulation(List<Solution> population) {
		this.population = population;
	}

	public double getObjectiveWeight() {
		return objectiveWeight;
	}

	public void setObjectiveWeight(double objectiveWeight) {
		this.objectiveWeight = objectiveWeight;
	}

	public double getPenaltyWeight() {
		return penaltyWeight;
	}

	public void setPenaltyWeight(double penaltyWeight) {
		this.penaltyWeight = penaltyWeight;
	}

	public double getSpeedWeight() {
		return speedWeight;
	}

	public void setSpeedWeight(double speedWeight) {
		this.speedWeight = speedWeight;
	}

	public double getDistanceWeight() {
		return distanceWeight;
	}

	public void setDistanceWeight(double distanceWeight) {
		this.distanceWeight = distanceWeight;
	}

	public double[] getObjectiveWeights() {
		return objectiveWeights;
	}

	public void setObjectiveWeights(double[] objectiveWeights) {
		this.objectiveWeights = objectiveWeights;
	}

	public double[] getPenaltyWeights() {
		return penaltyWeights;
	}

	public void setPenaltyWeights(double[] penaltyWeights) {
		this.penaltyWeights = penaltyWeights;
	}

	public List<SimpleCompareObject> getCompareList() {
		return compareList;
	}

	public void setCompareList(List<SimpleCompareObject> compareList) {
		this.compareList = compareList;
	}	
}
